package com.patchmanage.back.websocket;

import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.List;
import java.util.concurrent.CopyOnWriteArraySet;

import javax.websocket.server.ServerEndpoint;

import cn.hutool.core.util.RuntimeUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import cn.hutool.log.Log;
import cn.hutool.log.LogFactory;
import org.springframework.stereotype.Component;

import javax.websocket.*;

@ServerEndpoint("/websocket")
@Component
public class WebSocketServer {

    //静态变量，用来记录当前在线连接数。应该把它设计成线程安全的。
    private static int onlineCount = 0;
    //concurrent包的线程安全Set，用来存放每个客户端对应的MyWebSocket对象。
    private static CopyOnWriteArraySet<WebSocketServer> webSocketSet = new CopyOnWriteArraySet<WebSocketServer>();

    private static final Log log = LogFactory.get();

    //与某个客户端的连接会话，需要通过它来给客户端发送数据
    private Session session;

    /**
     * 连接建立成功调用的方法*/
    @OnOpen
    public void onOpen(Session session) {
        this.session = session;
        webSocketSet.add(this);     //加入set中
        addOnlineCount();           //在线数加1
/*       try {
            sendMessage("连接成功！");
        } catch (IOException e) {
            e.printStackTrace();
        }*/
    }

    /**
     * 连接关闭调用的方法
     */
    @OnClose
    public void onClose() {
        webSocketSet.remove(this);  //从set中删除
        subOnlineCount();           //在线数减1
    }

    /**
     * 收到客户端消息后调用的方法
     * @param message 客户端发送过来的消息
     */
    @OnMessage
    public void onMessage(String message, Session session) throws Exception{

        JSONObject jsonObject = JSONUtil.parseObj(message);

        String cmd = "";
        if (jsonObject.getInt("probeType") != null && StrUtil.isNotBlank(jsonObject.getStr("probeUrl"))) {

            Integer probeType = jsonObject.getInt("probeType");
            String probeUrl = jsonObject.getStr("probeUrl");

            List<String> returnContent = null;
            if (probeType == 0) {
                //ping
                String osName = System.getProperty("os.name");//获取操作系统类型
                log.info("====================网络探测操作系统：" + osName + "========================");
                if (osName.toLowerCase().contains("linux")) {
                    cmd = "ping -c 5 " + probeUrl;
                    log.info("====================网络探测执行命令：" + cmd + "========================");
                }

            } else if (probeType == 1) {
                //telnet
                String osName = System.getProperty("os.name");//获取操作系统类型
                log.info("====================网络探测操作系统：" + osName + "========================");
                if (osName.toLowerCase().contains("linux")) {
                    cmd = "telnet " + probeUrl;
                    log.info("====================网络探测执行命令：" + cmd + "========================");
                }

            } else if (probeType == 2) {
                //ssh

            } else if (probeType == 3) {
                //traceroute
                String osName = System.getProperty("os.name");//获取操作系统类型
                log.info("====================网络探测操作系统：" + osName + "========================");
                if (osName.toLowerCase().contains("linux")) {
                    cmd = "traceroute  -q 2 " + probeUrl;
                    log.info("====================网络探测执行命令：" + cmd + "========================");

                }

            }
            if(StrUtil.isNotBlank(cmd)){
                Process p =  RuntimeUtil.exec(cmd);
                BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream()));
                String line = "";
                while ((line = reader.readLine())!=null){
                    this.sendMessage(line);
                }
            }

        }
    }
    /**
     * 发生错误
     * @param session
     * @param error
     */
    @OnError
    public void onError(Session session, Throwable error) {
        error.printStackTrace();
    }


    public void sendMessage(String message) throws IOException {
        if(this.session != null){
            this.session.getBasicRemote().sendText(message);
        }
    }


    /**
     * 群发自定义消息
     * */
    public static void sendInfo(String message) throws IOException {
        for (WebSocketServer item : webSocketSet) {
            try {
                item.sendMessage(message);
            } catch (IOException e) {
                continue;
            }
        }
    }

    public static synchronized int getOnlineCount() {
        return onlineCount;
    }

    public static synchronized void addOnlineCount() {
        WebSocketServer.onlineCount++;
    }

    public static synchronized void subOnlineCount() {
        WebSocketServer.onlineCount--;
    }
}